package com.fy56.platform.logistics.restful.api.controller.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fy56.platform.logistics.common.ResultModel;
import com.fy56.platform.logistics.model.*;
import com.fy56.platform.logistics.service.web.IMiniProgramService;
import com.fy56.platform.logistics.service.web.IWeChatProgramService;
import com.fy56.platform.logistics.service.wx.ICompanyInfoService;
import com.fy56.platform.logistics.service.wx.IInsuranceService;
import com.fy56.platform.logistics.service.wx.IVipService;
import com.fy56.platform.logistics.utils.HttpClientUtils;
import com.fy56.platform.logistics.utils.MD5Util;
import com.fy56.platform.logistics.utils.StringUtil;
import com.google.common.collect.Maps;
import com.wordnik.swagger.annotations.Api;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 保险中心 - 投保相关接口InsuranceController
 *
 * @author  haitaoliu
 * @time    2019-03-19
 * @version
 */
@Api(value = "Insurance", description = "投保接口", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequestMapping("/insurance")
public class InsuranceController {


    private static Logger log = Logger.getLogger(InsuranceController.class);
    private static String APPLICATIONCODE = "TMS_BS";

    @Autowired
    private ICompanyInfoService iCompanyInfoService;
    @Autowired
    private IVipService iVipService;
    @Autowired
    private IMiniProgramService iMiniProgramService;
    @Autowired
    private IInsuranceService iInsuranceService;
    @Autowired
    private IWeChatProgramService iWeChatProgramService;

    /**
     * 投保登录
     *
     * http://localhost:8082/logistics-restful-api/insurance/loginInsurance
     * data = {"loginName":"7580","password":"123456"}
     */
    @RequestMapping(value = "/loginInsurance", method = RequestMethod.POST)
    public ResponseEntity loginInsurance(@RequestParam String data){
        ResultModel result = null;
        try{
            if(StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Map<String, Object> paramMap = JSON.parseObject(data);
                String paramsErrorMsg ="";
                Object loginName = paramMap.get("loginName");
                if(loginName == null || StringUtil.isEmpty(loginName.toString())){
                   paramsErrorMsg = "loginName用户名不可为空 ";
                }
                Object password = paramMap.get("password");
                if(password == null || StringUtil.isEmpty(password.toString())){
                   paramsErrorMsg += "password密码不可为空 ";
                }
                Object applicationCode = paramMap.get("applicationCode");
                if(applicationCode == null || StringUtil.isEmpty(applicationCode.toString())){
                    applicationCode = APPLICATIONCODE;
                }
                // 2 登录保险公司用户
                if (StringUtil.isEmpty(paramsErrorMsg)) {
                    result = iInsuranceService.loginInsuranceService(weChatProgram, loginName.toString(), password.toString(), applicationCode.toString());
                }else{
                    result = new ResultModel(101, paramsErrorMsg,null);
                }
            }else{
                result = new ResultModel(101, "获取险种列表数据：insuranceCodeList功能异常。",null);
            }
        }catch (Exception ex){
            log.error("保险用户登录异常-loginInsurance：",ex);
            result = new ResultModel(101, "保险用户登录异常-loginInsurance：" + ex.getMessage(),null);
        }
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 根据企业编码查询企业已绑定的保险公司列表
     *
     * http://localhost:8082/logistics-restful-api/insurance/insuranceCompanyByCompanyBinding
     * data = {"companyCode":"hljbsc"}
     */
    @RequestMapping(value = "/insuranceCompanyByCompanyBinding", method = {RequestMethod.POST, RequestMethod.GET })
    public ResponseEntity insuranceCompanyByCompanyBinding(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Map<String,Object> parameter = JSON.parseObject(data);
                //1 验证客户端传入参数
                String paramErrorMsg = null;
                Object companyCode = parameter.get("companyCode");
                if(companyCode == null || StringUtil.isEmpty(companyCode.toString())){
                    paramErrorMsg += "companyCode不可为空 ";
                }
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)) {
                    result = iInsuranceService.queryInsuranceCompanyByCompanyBindingService(weChatProgram, companyCode.toString());
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，根据企业编码查询企业已绑定的保险公司列表：insuranceCompanyByCompanyBinding功能异常：", ex);
            result = new ResultModel(101, "根据企业编码查询企业已绑定的保险公司列表：insuranceCompanyByCompanyBinding功能异常。",null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 险种列表查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/insuranceCodeList
     * data = {"userName":"7580","password":"123456","insuranceCompanyId":2,"bindingFlag":""}
     */
    @RequestMapping(value = "/insuranceCodeList", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity insuranceCodeList(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                //1 验证客户端传入参数
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                String insuranceCompanyId = parameter.get("insuranceCompanyId") == null? "" : parameter.get("insuranceCompanyId").toString();
                /*
                String bindingFlag = null;
                if(parameter.get("bindingFlag") == null || StringUtil.isEmpty(parameter.get("bindingFlag").toString())){
                    bindingFlag = "1";
                }else {
                    bindingFlag =  parameter.get("bindingFlag").toString();
                }
                */
                String bindingFlag = "1";
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)) {
                    // 先用带绑定标识为bindingFlag=1的参数查询，若没有保险列表，则用bindingFlag=""进行查询
                    result = iInsuranceService.insuranceCodeListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), insuranceCompanyId, bindingFlag);
                    if(result.getContent() == null){
                        bindingFlag = "";
                        result = iInsuranceService.insuranceCodeListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), insuranceCompanyId, bindingFlag);
                    }
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，获取险种列表数据：insuranceCodeList功能异常：", ex);
            result = new ResultModel(101, "获取险种列表数据：insuranceCodeList功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 参保人员列表查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/insuranceUserList
     * data = {"userName":"7580","password":"123456","insuranceUserType":"","insuranceCodeId":""}  insuranceUserType可以为空
     */
    @RequestMapping(value = "/insuranceUserList", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity insuranceUserList(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                // String paramErrorMsg = validataPayOrderParams(parameter, insurance,"code");
                String insuranceCodeId = parameter.get("insuranceCodeId") == null ? "" : parameter.get("insuranceCodeId").toString();
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)) {
                    Integer insuranceUserType = getIntValue(parameter.get("insuranceUserType"));

                    // 根据类型 获取投保人与被投保人信息
                    Integer code = 101;
                    String message = "";
                    Map<String, Object> contentMap = new HashMap<String, Object>();
                    if (insuranceUserType == null){
                        ResultModel insurancePreson   = iInsuranceService.queryInsuranceUserListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), 0, insuranceCodeId);
                        ResultModel insuranceToPreson = iInsuranceService.queryInsuranceUserListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), 1, insuranceCodeId);
                        code = insurancePreson.getCode();
                        message = insurancePreson.getMsg();
                        contentMap.put("insurancePreson", insurancePreson.getContent());
                        contentMap.put("insuranceToPreson", insuranceToPreson.getContent());
                    }else if(insuranceUserType == 0){
                        ResultModel resultModel = iInsuranceService.queryInsuranceUserListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), 0, insuranceCodeId);
                        code = resultModel.getCode();
                        message = resultModel.getMsg();
                        contentMap.put("insurancePreson", resultModel.getContent());
                        contentMap.put("insuranceToPreson", "");
                    }else if(insuranceUserType ==1){
                        ResultModel resultModel = iInsuranceService.queryInsuranceUserListService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), 1, insuranceCodeId);
                        code = resultModel.getCode();
                        message = resultModel.getMsg();
                        contentMap.put("insurancePreson", "");
                        contentMap.put("insuranceToPreson", resultModel.getContent());
                    }
                    result = new ResultModel(code, message, contentMap);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，参保人员列表查询接口：insuranceUserList功能异常：", ex);
            result = new ResultModel(101, "参保人员列表查询接口：insuranceUserList功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 投保须知查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/insuranceCodeNoticeContent
     * data = {"code":"7580","insuranceCodeId":"0"}
     */
    @RequestMapping(value = "/insuranceCodeNoticeContent", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity insuranceCodeNoticeContent(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                // String paramErrorMsg = validataPayOrderParams(parameter, insurance,"code");
                String insuranceCodeId = parameter.get("insuranceCodeId") == null ? "" : parameter.get("insuranceCodeId").toString();
                if(StringUtil.isEmpty(insuranceCodeId)){
                    paramErrorMsg += "insuranceCodeId不可为空 ";
                }
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)) {
                    result = iInsuranceService.queryInsuranceCodeNoticeContent(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), insuranceCodeId);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，投保须知查询接口：insuranceCodeNoticeContent功能异常：", ex);
            result = new ResultModel(101, "投保须知查询接口：insuranceCodeNoticeContent功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 保费计算
     *
     * http://localhost:8082/logistics-restful-api/insurance/calculate
     * data = {"userName":"7580","password":"123456","insuranceCompanyId":"123","insuranceCodeId":"12","sumInsured":"12.3","fromArea":"","toArea":""}
     */
    @RequestMapping(value = "/calculate", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity calculate(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                Integer insuranceCompanyId = getIntValue(parameter.get("insuranceCompanyId"));
                if(insuranceCompanyId == null || StringUtil.isEmpty(insuranceCompanyId.toString())){
                    paramErrorMsg += "insuranceCompanyId不可为空 ";
                }
                Integer insuranceCodeId = getIntValue(parameter.get("insuranceCodeId"));
                if(insuranceCodeId == null){
                    paramErrorMsg += "insuranceCodeId不可为空或类型错误 ";
                }
                Double sumInsured = getDoubleValue(parameter.get("sumInsured"));
                if(sumInsured == null || sumInsured <= 0D ){
                    paramErrorMsg += "sumInsured不可为空或金额不正确 ";
                }
                String fromArea = parameter.get("fromArea") == null ? "" : parameter.get("fromArea").toString() ;
                String toArea   = parameter.get("toArea")   == null ? "" : parameter.get("toArea").toString() ;

                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)) {
                    result = iInsuranceService.calculateService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), insuranceCompanyId, insuranceCodeId, sumInsured, fromArea, toArea);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，保费计算接口：calculate功能异常：", ex);
            result = new ResultModel(101, "保费计算接口：calculate功能异常。"  + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 投保结果通知
     *
     * http://localhost:8082/logistics-restful-api/insurance/updateInsuranceResultNotice
     * data = {"sumInsured": 1000000,"premium": 30,"insuranceBillUrl": "保单下载地址", "transactionOrderNo": "保险中心受理单号","stateFlag": 1,"premiumRate": 0.00001,
     "consignmentNumber": "业务系统业务单号",
     "insuranceBillCode": "保险公司保单号"}
     */
    @RequestMapping(value = "/updateInsuranceResultNotice", method = {RequestMethod.POST,RequestMethod.GET})
    public ResponseEntity updateInsuranceResultNotice(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Map<String,Object> parameter = JSON.parseObject(data);
                if(parameter != null && !parameter.isEmpty()) {
                    String consignmentNumber = getStringValue(parameter.get("consignmentNumber"));
                    String insuranceBillCode = getStringValue(parameter.get("insuranceBillCode"));
                    String transactionOrderNo= getStringValue(parameter.get("transactionOrderNo"));
                    Integer stateFlag = getIntValue(parameter.get("stateFlag"));
                    String insuranceBillUrl = getStringValue(parameter.get("insuranceBillUrl"));
                    result = iInsuranceService.updateInsuranceResultNoticeService(consignmentNumber, insuranceBillCode,transactionOrderNo, stateFlag, insuranceBillUrl, data);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，投保结果通知接口：updateInsuranceResultNotice功能异常：", ex);
            result = new ResultModel(101, "投保结果通知接口：updateInsuranceResultNotice功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        System.out.println("updateInsuranceResultNotice：param="+ data + ", result= " + result);
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /* 投保单数据
    {"userName":"7580","password":"123456","calculateWithArea":"1",
        "data":{
        "consignmentNumber": "D101,D102",
        "goodsNames":"大饼二锅头",
        "orderQuantity":12,
        "orderCount":6,
        "fromArea":"上海",
        "toArea":"哈尔滨",
        "consignmentTime":"2019-03-26",
        "vehicleNumber":"黑ANB110",
        "driver":"司机one",
        "driverPhone":"13625252250",
        "insuranceCodeId":"42",
        "applicantUserName":"投保人",
        "insuredUserName":"被投保人",
        "sumInsured":10000,
        "premiumRate":0.0002,
        "premium":"60.00",
        "insuranceImageUrl":"http://123456",

        "applicantUserGender":"0",
        "applicantUserBirthday":"2019-03-27",
        "applicantIdType":0,
        "applicantPhone":"13000000000移动电弧",
        "applicantCell":"0452-14251425固话",
        "applicantZip":"邮编",
        "applicantAddress":"投保人地址",
        "applicantEmail":"123@qq.com",
        "insuredUserGender":1,
        "insuredUserBirthday":"2019-03-28",
        "insuredIdType":0,
        "insuredPhone":"1500000000",
        "insuredCell":"固话",
        "insuredZip":"邮编",
        "insuredAddress":"被投保人地址",
        "insuredEmail":"456@qq.com",
        "driverLicense":"驾驶证",

        "notifyUrl":"http://localhost:8082/abc"
        }
    }
    */
    /**
     * 保单添加及投递
     *
     * http://localhost:8082/logistics-restful-api/insurance/addInsurance
     * data = {"userName":"7580","password":"123456","data":{},"calculateWithArea":"0"}
     */
    @RequestMapping(value = "/addInsurance", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity addInsurance(@RequestParam String data) {
        log.info("执行start时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") +", 投保接口[addInsurance] params-data：" +data);
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();
                Map<String,Object> parameter = JSON.parseObject(data);

                // 1 验证保险表单参数
                Insurance insurance = new Insurance();
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                String insuranceData = getInsureJsonDateValue(parameter.get("data")== null?"":parameter.get("data").toString(), weChatProgram.getInsuranceResultNotifyUrl());
                if(StringUtil.isEmpty(insuranceData)){
                    paramErrorMsg += "data不可为空 ";
                }
                Object calculateWithArea = parameter.get("calculateWithArea");
                if(calculateWithArea == null || StringUtil.isEmpty(calculateWithArea.toString())){
                    calculateWithArea = "0";
                }
                Map<String,Object> insuranceMap = JSON.parseObject(insuranceData);
                String consignmentNumber = getStringValue(insuranceMap.get("consignmentNumber"));
                if(StringUtil.isEmpty(consignmentNumber)){
                    paramErrorMsg += "consignmentNumber不可为空 ";
                }

                if (StringUtil.isEmpty(paramErrorMsg)){
                    result = iInsuranceService.addInsuranceService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), insuranceData, calculateWithArea.toString(), consignmentNumber);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，保单添加及投递接口：addInsurance功能异常：", ex);
            result = new ResultModel(101, "保单添加及投递接口：addInsurance功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        log.info("执行end时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") +", 投保接口[addInsurance] result：code=" + result.getCode() + ", message:" + result.getMsg());
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 公司账户余额查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/queryCompanyAccount
     * data = {"userName":"7580","password":"123456","typeCode":"保险"}
     */
    @RequestMapping(value = "/queryCompanyAccount", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity queryCompanyAccount(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                String typeCode = getStringValue(parameter.get("typeCode"));
                if(StringUtil.isEmpty(typeCode)){
                    typeCode = "保险";
                }
                // 2 查询保险账户余额
                if (StringUtil.isEmpty(paramErrorMsg)){
                    result = iInsuranceService.queryCompanyAccountService(weChatProgram,insurance.getUserName(), insurance.getPassword(), typeCode);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，公司账户余额查询递口：queryCompanyAccount功能异常：", ex);
            result = new ResultModel(101, "公Insurance投保接口，司账户余额查询递口：queryCompanyAccount功能异常：" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 公司账户余额查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/queryCompanyAccount
     * data = {"userName":"7580","password":"123456","typeCode":"保险"}
     */
    @RequestMapping(value = "/queryBalance", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity queryBalance(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();
                Map<String,Object> parameter = JSON.parseObject(data);
                Map<String, String> params = Maps.newHashMap();
                params.put("loginName", parameter.get("userName").toString());
                params.put("password", parameter.get("password").toString());
                params.put("typeCode", parameter.get("typeCode")+"");
                String postData = HttpClientUtils.post(weChatProgram.getTradingcenterUrl() + "/consumeManager/queryBalance", params, null, 10000, 10000);
                if(StringUtil.isNotEmpty(postData)){
                    Map<String,Object> resultMap = JSON.parseObject(postData);
                    Object object = resultMap.get("object");
                    Map<String, Object> objectMap = JSONObject.parseObject(object.toString(), Map.class);
                    String couponBalance = objectMap.get("couponBalance") != null ? objectMap.get("couponBalance").toString() : "";
                    if(couponBalance!=null){
                        couponBalance=new BigDecimal(couponBalance).stripTrailingZeros().toPlainString();
                    }
                    result = new ResultModel(100, "余额查询成功", couponBalance);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，公司账户余额查询递口：queryCompanyAccount功能异常：", ex);
            result = new ResultModel(101, "公Insurance投保接口，司账户余额查询递口：queryCompanyAccount功能异常：" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }


    /**
     * 保单详情查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/queryOne
     * data = {"userName":"7518","password":"123456","transactionOrderNo":"0"}
     */
    @RequestMapping(value = "/queryOne", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity queryOne(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                String transactionOrderNo = getStringValue(parameter.get("transactionOrderNo"));
                if(StringUtil.isEmpty(transactionOrderNo)){
                    paramErrorMsg += "transactionOrderNo不可为空 ";
                }
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)){
                    result = iInsuranceService.queryOneService(weChatProgram,insurance, insurance.getUserName(), insurance.getPassword(), transactionOrderNo);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，保单详情查询接口：queryOne功能异常：", ex);
            result = new ResultModel(101, "保单详情查询接口：queryOne功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

    /**
     * 保单列表查询
     *
     * http://localhost:8082/logistics-restful-api/insurance/queryList
     * data = {"userName":"7580","password":"123456","startDate":"2019-01-01 00:00:00","endDate":"2019-03-27 23:59:59", "stateFlag":1}
     */
    @RequestMapping(value = "/queryList", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity queryList(@RequestParam String data) {
        ResultModel result = null;
        try{
            if (StringUtil.isNotEmpty(data)){
                WeChatProgram weChatProgram = iWeChatProgramService.getWeChatProgram();

                Insurance insurance = new Insurance();
                Map<String,Object> parameter = JSON.parseObject(data);
                String paramErrorMsg = validataPayOrderParams(parameter, insurance,"userName-password");
                String startDate = getStringValue(parameter.get("startDate"));
                if(StringUtil.isEmpty(startDate)){
                    paramErrorMsg += "startDate不可为空 ";
                }
                String endDate = getStringValue(parameter.get("endDate"));
                if(StringUtil.isEmpty(endDate)){
                    paramErrorMsg += "endDate不可为空 ";
                }
                Integer stateFlag = getIntValue(parameter.get("stateFlag"));
                Integer page = getIntValue(parameter.get("page"));
                Integer pageSize = getIntValue(parameter.get("pageSize"));
                // 2 查询险种列表数据
                if (StringUtil.isEmpty(paramErrorMsg)){
                    result = iInsuranceService.queryListService(weChatProgram, insurance, insurance.getUserName(), insurance.getPassword(), startDate, endDate, stateFlag, page, pageSize);
                }else{
                    result = new ResultModel(101, paramErrorMsg,null);
                }
            }
        }catch (Exception ex){
            log.error("Insurance投保接口，保单列表查询接口：queryList功能异常：", ex);
            result = new ResultModel(101, "保单列表查询接口：queryList功能异常。" + ex.getMessage(),null);
            ex.printStackTrace();
        }
        return  new ResponseEntity<>(result, HttpStatus.OK);
    }

   /**
     * 解析数据 返回投保格式信息
     *
     * @param data
     * @return
     */
    private String getInsureJsonDateValue(String data, String insuranceResultNotifyUrl)throws  Exception{
        String result = "";
        Map<String,Object> parameter = JSON.parseObject(data);
        StringBuffer resultJson = new StringBuffer(600);
        if(parameter != null && !parameter.isEmpty()) {

            // 验证保单险种是否为 杭州人保[yes：更改投保时间，no：不需要更改投保时间] getStringValue(parameter.get("consignmentTime"))
            String consignmentTime = getCreateConsignmentTime(getStringValue(parameter.get("insuranceCompanyName")), "", 5);
            String transactionOrderNo = getStringValue(parameter.get("transactionOrderNo"));
            resultJson.append("{");
            /** 保险交易单号{全局唯一}
             * data中如果包含transactionOrderNo字段，则其他参数无效，按转投处理
             * 如果不包含transactionOrderNo字段，按新增并投递处理
             */
            if(StringUtil.isNotEmpty(transactionOrderNo)){
                // 保险交易单号
                resultJson.append("\"transactionOrderNo\": \""+ transactionOrderNo +"\",");
            }
            resultJson.append("\"insuredIdNo\": \""+ getStringValue(parameter.get("insuredIdNo")) +"\",");                  // 证件号
            resultJson.append("\"insuredUserGender\":\""+ getStringValue(parameter.get("insuredUserGender")) +"\",");      // 被投保人性别 {0男 1女}
            resultJson.append("\"orderCube\": \""+ getStringValue(parameter.get("orderCube")) +"\",");                       // 货物总体积
            resultJson.append("\"insuredUserBirthday\": \""+ getStringValue(parameter.get("insuredUserBirthday")) +"\","); // 被投保人生日
            resultJson.append("\"applicantUserName\": \""+ getStringValue(parameter.get("applicantUserName")) +"\",");      // 投保人姓名
            resultJson.append("\"toArea\": \"" + getStringValue(parameter.get("toArea")) + "\",");                             // 目的地
            resultJson.append("\"applicantCell\": \""+ getStringValue(parameter.get("applicantCell")) +"\",");               // 申请人固定电话
            resultJson.append("\"premiumRate\": \""+ getStringValue(parameter.get("premiumRate")) +"\",");                        // 费率
            resultJson.append("\"applicantUserGender\": \""+ getStringValue(parameter.get("applicantUserGender")) +"\",");      // 投保人性别 {0男 1女}
            resultJson.append("\"orderWeight\": \""+ getStringValue(parameter.get("orderWeight")) +"\",");                        // 货物总重量
            resultJson.append("\"remark\": \""+ getStringValue(parameter.get("remark")) +"\",");                               // 备注 【非必填】
            resultJson.append("\"orderQuantity\":\""+ getStringValue(parameter.get("orderQuantity")) +"\",");                    // 总件数
            resultJson.append("\"fromArea\": \""+ getStringValue(parameter.get("fromArea")) +"\",");                           // 起运地
            resultJson.append("\"licenseplateTypeCode\": \""+ getStringValue(parameter.get("licenseplateTypeCode")) +"\",");// 牌照类型代码{0公路运输}
            resultJson.append("\"goodsNames\": \""+ getStringValue(parameter.get("goodsNames")) +"\",");                         // 商品信息
            resultJson.append("\"sumInsured\": \""+ getStringValue(parameter.get("sumInsured")) +"\",");                         // 保险额
            resultJson.append("\"premium\": \""+ getStringValue(parameter.get("premium")) +"\",");                                // 保费
            resultJson.append("\"insuranceCompanyName\": \""+ getStringValue(parameter.get("insuranceCompanyName")) +"\",");   // 保险公司名称
            resultJson.append("\"insuranceCodeId\": \""+ getStringValue(parameter.get("insuranceCodeId")) +"\",");              // 险种ID
            resultJson.append("\"insuranceName\": \""+ getStringValue(parameter.get("insuranceName")) +"\",");                   // 险种名称
            resultJson.append("\"insuredUserName\": \""+ getStringValue(parameter.get("insuredUserName")) +"\",");              // 被投保人姓名
            resultJson.append("\"vehicleNumber\": \""+ getStringValue(parameter.get("vehicleNumber")) +"\",");                  // 车牌号
            resultJson.append("\"driverLicense\": \""+ getStringValue(parameter.get("driverLicense")) +"\",");                  // 驾驶证信息
            resultJson.append("\"applicantIdNo\": \""+ getStringValue(parameter.get("applicantIdNo")) +"\",");                 // 证件号
            resultJson.append("\"insuredPhone\": \""+ getStringValue(parameter.get("insuredPhone")) +"\",");                   // 被申请人移动电话
            resultJson.append("\"consignmentTime\": \""+ consignmentTime +"\",");                                               // 起运时间
            resultJson.append("\"detailedList\":"+ getDetailedListValue(getStringValue(parameter.get("detailedList")), getStringValue(parameter.get("orderQuantity"))) +",");                                      // 保单明细
            resultJson.append("\"applicantAddress\": \""+ getStringValue(parameter.get("applicantAddress")) +"\",");          // 收件地址
            resultJson.append("\"insuredIdType\": \""+ getStringValue(parameter.get("insuredIdType")) +"\",");                 // 证件类型  ｛0 身份证｝
            resultJson.append("\"insuredCell\": \""+ getStringValue(parameter.get("insuredCell")) +"\",");                     // 被申请人固定电话
            resultJson.append("\"orderCount\": \""+ getStringValue(parameter.get("orderCount")) + "\",");                      // 总单数
            resultJson.append("\"consignmentNumber\": \""+ getStringValue(parameter.get("consignmentNumber")) +"\",");       // 业务单号{如配载编号}
            resultJson.append("\"applicantUserCode\": \""+ getStringValue(parameter.get("applicantUserCode")) +"\",");   // 投保人编码
            resultJson.append("\"applicantEmail\": \""+ getStringValue(parameter.get("applicantEmail")) +"\",");          // 投保人电子邮箱
            resultJson.append("\"goodsType\": \""+ getStringValue(parameter.get("goodsType")) +"\",");                     // 商品类别
            resultJson.append("\"applicantZip\": \""+ getStringValue(parameter.get("applicantZip")) +"\",");              // 邮编
            resultJson.append("\"driver\": \""+ getStringValue(parameter.get("driver")) +"\",");                            // 驾驶员信息
            resultJson.append("\"applicantUserBirthday\": \""+ getStringValue(parameter.get("applicantUserBirthday")) +"\",");  // 投保人生日
            resultJson.append("\"applicantIdType\": \""+ getStringValue(parameter.get("applicantIdType")) + "\",");              // 证件类型｛0 身份证｝
            resultJson.append("\"insuredUserCode\": \""+ getStringValue(parameter.get("insuredUserCode")) +"\",");       // 被投保人编码
            resultJson.append("\"insuredEmail\": \""+ getStringValue(parameter.get("insuredEmail")) +"\",");              // 被投保人电子邮箱
            resultJson.append("\"notifyUrl\": \""+ insuranceResultNotifyUrl + "/insurance/updateInsuranceResultNotice" +"\","); // 通知回调地址
            resultJson.append("\"insuredZip\": \""+ getStringValue(parameter.get("insuredZip")) +"\",");                  // 邮编
            resultJson.append("\"driverPhone\": \""+ getStringValue(parameter.get("driverPhone")) +"\",");                // 驾驶员电话
            resultJson.append("\"roadLicenseNumber\": \""+ getStringValue(parameter.get("roadLicenseNumber")) +"\",");
            resultJson.append("\"frameNumber\": \""+ getStringValue(parameter.get("frameNumber")) +"\",");
            resultJson.append("\"transportVehiclesApprovedTotal\": \""+ getStringValue(parameter.get("transportVehiclesApprovedTotal")) +"\",");
            resultJson.append("\"insuredAddress\": \""+ getStringValue(parameter.get("insuredAddress")) +"\",");         // 收件地址
            resultJson.append("\"imageCount\": \""+ getStringValue(parameter.get("imageCount")) +"\",");          // 图片数量
            resultJson.append("\"images\": \""+ getStringValue(parameter.get("images")) +"\",");          // 图片地址串，逗号分隔
            resultJson.append("\"imageNames\": \""+ getStringValue(parameter.get("imageNames")) +"\",");          // 显示图片名称串，逗号分隔
            resultJson.append("\"applicantPhone\": \""+ getStringValue(parameter.get("applicantPhone")) +"\",");          // 申请人移动电话
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("insuranceIdValidStart")))) {
                resultJson.append("\"insuredIdValidStart\": \"" + getStringValue(parameter.get("applicantIdValidStart")) + "\","); // 被投保人证件有效期起始日期
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("insuranceIdValidEnd")))) {
                resultJson.append("\"insuredIdValidEnd\": \""+ getStringValue(parameter.get("applicantIdValidEnd")) +"\","); //被投保人证件有效期终止日期
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("insuranceUnitProperties")))) {
                resultJson.append("\"insuredUnitProperties\": \""+ getStringValue(parameter.get("applicantUnitProperties")) +"\","); //被投保人单位性质
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("insuranceRecognizeeLinkMan")))) {
                resultJson.append("\"insuredRecognizeeLinkMan\": \""+ getStringValue(parameter.get("applicantRecognizeeLinkMan")) +"\","); //被投保人单位联系人
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("insuranceOverseasFlag")))) {
                resultJson.append("\"insuredOverseasFlag\": \""+ getStringValue(parameter.get("applicantOverseasFlag")) +"\","); // 被投保人是否为境外{0否，1是}
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("applicantIdValidStart")))) {
                resultJson.append("\"applicantIdValidStart\": \""+ getStringValue(parameter.get("insuranceIdValidStart")) +"\",");  // 投保人证件有效期起始日期
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("applicantIdValidEnd")))) {
                resultJson.append("\"applicantIdValidEnd\": \""+ getStringValue(parameter.get("insuranceIdValidEnd")) +"\",");  // 投保人证件有效期终止日期
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("applicantUnitProperties")))) {
                resultJson.append("\"applicantUnitProperties\": \""+ getStringValue(parameter.get("insuranceUnitProperties")) +"\",");  //投保人单位性质
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("applicantRecognizeeLinkMan")))) {
                resultJson.append("\"applicantRecognizeeLinkMan\": \""+ getStringValue(parameter.get("insuranceRecognizeeLinkMan")) +"\",");  //投保人单位联系人
            }
            if(StringUtil.isNotEmpty(getStringValue(parameter.get("applicantOverseasFlag")))) {
                resultJson.append("\"applicantOverseasFlag\": \""+ getStringValue(parameter.get("insuranceOverseasFlag")) +"\",");    //投保人是否为境外{0否，1是}
            }
            if(",".equals(resultJson.substring(resultJson.length() - 1, resultJson.length()))){
                resultJson.deleteCharAt(resultJson.length() - 1);
            }
            resultJson.append("}");
            result = resultJson.toString();
        }
        return result;
    }

    private String getDetailedListValue(String dataList, String orderQuantity){
        String  result = "";
        if(StringUtil.isEmpty(dataList)){
            result = new String("[{\"orderCube\": 0,\"consignee\": \"默认\",\"goodsReceiptPlace\": \"默认\",\"remark\": \"默认\"," +
                    "\"orderWeight\": 0,\"shippingNoteNumber\": \"默认\",\"packageType\": \"默认\",\"orderQuantity\":\""+ orderQuantity +"\",\"placeOfLoading\": \"默认\"," +
                    "\"goodsName\": \"默认\",\"consignor\": \"默认\"}]");
        }else{
            // 解析货物详情数据 拼接JSON数据对象
            result = dataList;
        }
        return result;
    }

    /**
     * 判断保险名称，若是杭州人保更改发车日期
     *
     * @param insuranceCompanyName 保险公司名称
     * @param consignmentTime 启运时间
     * @param number 相加的分钟数据
     * @return
     */
    private String getCreateConsignmentTime(String insuranceCompanyName, String consignmentTime, Integer number ) throws  Exception{
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String resultTime = "";

        Date inTime = null;
        if(StringUtil.isNotEmpty(consignmentTime)){
            inTime = format.parse(consignmentTime);
        }else{
            inTime = new Date();
        }
        if ("杭州人保".equals(insuranceCompanyName)){
            Date lastTime = null;
            // 获取输入的时间 与相加分钟数后的时间
            Calendar inCalendar = Calendar.getInstance();
            inCalendar.setTime(inTime);
            Calendar afterTimeCalendar = Calendar.getInstance();
            afterTimeCalendar.setTime(inTime);
            afterTimeCalendar.add(Calendar.MINUTE, number);

            // 获取时间小时数是否相同
            Integer inHour = inCalendar.get(Calendar.HOUR_OF_DAY);
            Integer afterHour = afterTimeCalendar.get(Calendar.HOUR_OF_DAY);
            if(inHour != afterHour){
                // 将分钟数减去到00分
                afterTimeCalendar.add(Calendar.MINUTE, -(afterTimeCalendar.get(Calendar.MINUTE)));
                afterTimeCalendar.add(Calendar.SECOND, -(afterTimeCalendar.get(Calendar.SECOND)-2));
                lastTime =  afterTimeCalendar.getTime();
            }else{
                lastTime =  inCalendar.getTime();
            }
            resultTime = format.format(lastTime);
            System.out.println(inHour + " 当前时间：" + format.format(inCalendar.getTime()));
            System.out.println(afterHour + " 计算时间：" + format.format(afterTimeCalendar.getTime()));
        } else {
            resultTime = format.format(inTime);
        }
        return resultTime;
    }

    public static void main(String[] args)throws  Exception{
        InsuranceController cur = new InsuranceController();
        String temp = cur.getCreateConsignmentTime("杭州人保","2019-04-02 23:56:00", 5);
        System.out.println("result: " + temp);
    }

    /**
     * 获取Integer 转换值
     *
     * @param value
     * @return
     */
    private String getStringValue(Object value){
        String result = "";
        try {
            if (value != null && StringUtil.isNotEmpty(value.toString())) {
                result = value.toString();
            }
        }catch (Exception ex){}
        return  result;
    }

    /**
     * 获取Integer 转换值
     *
     * @param value
     * @return
     */
    private Integer getIntValue(Object value){
        Integer result = null;
        try {
            if (value != null) {
                result = Integer.parseInt(value.toString());
            }
        }catch (Exception ex){}
        return  result;
    }

    private Double getDoubleValue(Object value){
        Double result = null;
        try {
            if (value != null) {
                result = Double.parseDouble(value.toString());
            }
        }catch (Exception ex){}
        return  result;
    }

    /**
     * 验证方法传入参数是否合法
     *
     * @param parameter
     * @param insurance
     * @return
     */
    private String validataPayOrderParams(Map<String, Object> parameter, Insurance insurance, String validateParams){
        String resultVaildataMsg = "";
        // 1 验证金融平台公司编码 对应公司是否存在
        if(validateParams.indexOf("code") > -1){
           Object code = parameter.get("code");
            if(code != null && StringUtil.isNotEmpty(code.toString())){
                // 获取code对应关联的小程序设置信息
                MiniProgram miniProgram = iMiniProgramService.selectByCode(code.toString());
                if(miniProgram != null && StringUtil.isNotEmpty(miniProgram.getTradingcenterUrl()) && StringUtil.isNotEmpty(miniProgram.getTradingcenterMchKey())){
                    insurance.setAppId(miniProgram.getAppid());
                    insurance.setMiniProgram(miniProgram);
                }
                // 获取code 对应关联的company 信息
                Company company =  iCompanyInfoService.getCompanyByCode(code.toString());
                if(company != null){
                    insurance.setCompany(company);
                }else{
                    resultVaildataMsg += "code无对应公司信息 ";
                }
                insurance.setCode(code.toString());
            }else{
                resultVaildataMsg += "code参数有误 ";
            }
        }
        // 2 验证用户信息是否存在
        if (validateParams.indexOf("mobile") > -1){
            Object mobile = parameter.get("mobile");
            if(mobile != null && StringUtil.isNotEmpty(mobile.toString())){
                insurance.setMobile(mobile.toString());
            }else{
                resultVaildataMsg += "mobile不可为空 ";
            }
        }
        // 3 验证用户信息是否存在
        if (validateParams.indexOf("userName") > -1){
            Object userName = parameter.get("userName");
            if(userName != null && StringUtil.isNotEmpty(userName.toString())){
                insurance.setUserName(userName.toString());
            }else{
                resultVaildataMsg += "userName不可为空 ";
            }
        }
        // 4 验证密码信息息是否存在
        if (validateParams.indexOf("password") > -1){
            Object password = parameter.get("password");
            if(password != null && StringUtil.isNotEmpty(password.toString())){
                insurance.setPassword(password.toString());
            }else{
                resultVaildataMsg += "password不可为空 ";
            }
        }
        return resultVaildataMsg;
    }


}
